package com.ybear.ybcomponent.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.ViewGroup;

import androidx.annotation.ColorInt;

import com.ybear.ybcomponent.R;
import com.ybear.ybcomponent.Utils;
import com.ybear.ybcomponent.widget.shape.ShapeTextView;

/**
 * 小红点控件
 *
 * 设置小红点最小宽度、最小高度。当没有文本时自动切换成最小大小
 * @see #setRedDotMinSize(int)
 *
 * 小红点最小宽度
 * @see #setRedDotMinWidth(int)
 *
 * 小红点最小高度
 * @see #setRedDotMinHeight(int)
 *
 * 设置是否启用当不存在文本内容时自动改变成最小大小
 * @see #setEnableAutoMinSize(boolean)
 *
 *
 * 获取测量的文本长度
 * @see #getMeasureText()
 *
 * 获取小红点额外宽度
 * @see #getRedDotExtraWidth()
 *
 * 设置小红点额外宽度。
 * @see #setRedDotExtraWidth(int)
 *
 * 获取小红点额外自动宽度
 * @see #getRedDotExtraAutoWidth()
 *
 * 设置小红点额外自动宽度。小红点宽度由文本长度决定，所以可以通过该方法增加额外宽度，仅内容>=1时有效
 * @see #setRedDotExtraAutoWidth(int)
 *
 */
public class RedDotView extends ShapeTextView {
    private Paint mMeasurePaint;

    private int mOffsetWidth, mOffsetHeight, mExtraAutoWidth, mExtraWidth;
    private int mInitWidth = -1, mRedDotMinWidth, mRedDotMinHeight;
    private boolean isAutoMinSize;

    public RedDotView(Context context) { this(context, null); }

    public RedDotView(Context context, AttributeSet attrs) { this(context, attrs, 0); }

    public RedDotView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    private void initTypeArray(Context context, AttributeSet attrs) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RedDotView);

        //小红点最小宽度
        mRedDotMinWidth = typedArray.getDimensionPixelSize(
                R.styleable.RedDotView_redDotMinWidth, 10
        );
        //小红点最小高度
        mRedDotMinHeight = typedArray.getDimensionPixelSize(
                R.styleable.RedDotView_redDotMinHeight, 10
        );
        //小红点偏移宽度
        mOffsetWidth = typedArray.getDimensionPixelSize(
                R.styleable.RedDotView_redDotOffsetWidth, 0
        );
        //小红点偏移高度
        mOffsetHeight = typedArray.getDimensionPixelSize(
                R.styleable.RedDotView_redDotOffsetHeight, 0
        );
        //小红点额外宽度
        mExtraWidth = typedArray.getDimensionPixelSize(
                R.styleable.RedDotView_redDotExtraWidth, 0
        );
        //小红点额外宽度（自动）
        mExtraAutoWidth = typedArray.getDimensionPixelSize(
                R.styleable.RedDotView_redDotExtraAutoWidth, 0
        );
        //是否启用自动最小宽度
        isAutoMinSize = typedArray.getBoolean(
                R.styleable.RedDotView_redDotAutoMinSize, true
        );
        //描边大小
        setBorderSize(typedArray.getDimensionPixelSize(
                R.styleable.RedDotView_redDotBorderSize, 0
        ));
        //描边颜色
        setBorderColor(typedArray.getColor(
                R.styleable.RedDotView_redDotBorderColor, Color.WHITE
        ));
        //阴影半径
        setShadowRadius(typedArray.getDimensionPixelSize(
                R.styleable.RedDotView_redDotShadowRadius, 0
        ));
        //阴影颜色
        setShadowColor(typedArray.getColor(
                R.styleable.RedDotView_redDotShadowColor, 0
        ));
        //阴影偏移X
        setShadowOffsetX(typedArray.getDimensionPixelSize(
                R.styleable.RedDotView_redDotShadowOffsetX, 0
        ));
        //阴影偏移Y
        setShadowOffsetY(typedArray.getDimensionPixelSize(
                R.styleable.RedDotView_redDotShadowOffsetY, 0
        ));

        typedArray.recycle();

    }
    private void init(Context context, AttributeSet attrs) {
        initTypeArray(context, attrs);
        setShape( Shape.ROUND_RECT );
        setRadius( Utils.dp2Px( getContext(), 180 ) );

        mMeasurePaint = new Paint();
        //设置抗锯齿
        mMeasurePaint.setAntiAlias( true );
        setBackgroundResource( R.color.colorRedDot );
        setGravity( Gravity.CENTER );
        //只能显示一行
        setMaxLines( 1 );
    }

    @Override
    public void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);
        //根据内容改变宽度
        doChangeWidth( getWidth() );
    }

    /**
     * 设置小红点最小宽度、最小高度
     * @param size      高度和宽度
     * @return          {@link RedDotView}
     */
    public RedDotView setRedDotMinSize(int size) {
        mRedDotMinWidth = size;
        mRedDotMinHeight = size;
        return this;
    }

    public int getRedDotMinWidth() { return mRedDotMinWidth; }
    /**
     * 小红点最小宽度
     * @param width     宽度
     * @return          {@link RedDotView}
     */
    public RedDotView setRedDotMinWidth(int width) {
        mRedDotMinWidth = width;
        return this;
    }

    public int getRedDotMinHeight() { return mRedDotMinHeight; }
    /**
     * 小红点最小高度
     * @param height    高度
     * @return          {@link RedDotView}
     */
    public RedDotView setRedDotMinHeight(int height) {
        mRedDotMinHeight = height;
        return this;
    }

    /**
     * 设置是否启用当不存在文本内容时自动改变成最小大小
     * @param enable    是否启用
     * @return          {@link RedDotView}
     */
    public RedDotView setEnableAutoMinSize(boolean enable) {
        isAutoMinSize = enable;
        return this;
    }

    /**
     * 获取小红点额外宽度
     * @return  宽度
     */
    public int getRedDotExtraWidth() { return mExtraWidth; }

    /**
     * 设置小红点额外宽度
     * @param extraWidth          宽度
     * @return                    {@link RedDotView}
     */
    public RedDotView setRedDotExtraWidth(int extraWidth) {
        mExtraWidth = extraWidth;
        return this;
    }

    /**
     * 获取小红点额外自动宽度
     * @return  宽度
     */
    public int getRedDotExtraAutoWidth() { return mExtraAutoWidth; }

    /**
     * 设置小红点额外自动宽度
     * @param extraWidth        额外宽度
     * @return                  {@link RedDotView)
     */
    public RedDotView setRedDotExtraAutoWidth(int extraWidth) {
        this.mExtraAutoWidth = Utils.dp2Px(getContext(), extraWidth);
        return this;
    }

    public int getOffsetWidth() { return mOffsetWidth; }
    public RedDotView setOffsetWidth(int offsetWidth) {
        mOffsetWidth = offsetWidth;
        return this;
    }

    public int getOffsetHeight() { return mOffsetHeight; }
    public RedDotView setOffsetHeight(int offsetHeight) {
        mOffsetHeight = offsetHeight;
        return this;
    }

    public int getExtraAutoWidth() { return mExtraAutoWidth; }
    public RedDotView setExtraAutoWidth(int extraAutoWidth) {
        mExtraAutoWidth = extraAutoWidth;
        return this;
    }

    public int getExtraWidth() { return mExtraWidth; }
    public RedDotView setExtraWidth(int extraWidth) {
        mExtraWidth = extraWidth;
        return this;
    }

    /**
     * 获取测量的文本长度
     * @return  文本的实际长度
     */
    public int getMeasureText() {
        mMeasurePaint.setTextSize( getTextSize() );
        return (int) mMeasurePaint.measureText(getText().toString());
    }

    /**
     * 根据内容改变宽度
     */
    private void doChangeWidth(int width) {
        ViewGroup.LayoutParams lp;
        int len;
        if( mInitWidth == -1 && width != 0 ) mInitWidth = width;
        if( mInitWidth == - 1 ) return;
        lp = getLayoutParams();
        len = getText().length();
        if( isAutoMinSize && len == 0 ) {
            lp.width = mRedDotMinWidth;
            lp.height = mRedDotMinHeight;
        }else {
            lp.width = len <= 1 ? mInitWidth : mInitWidth + getMeasureText() + mExtraAutoWidth;
        }
        lp.width += mOffsetWidth + mExtraWidth;
        lp.height += mOffsetHeight;
        //会出现requestLayout()死循环
//        setLayoutParams( lp );
        //禁用自动最小尺寸时且文本为空时隐藏控件
        if( len == 0 ) setVisibility( isAutoMinSize ? VISIBLE : GONE );
    }
}